import json
import logging
import asyncio
import aiomysql
import akshare as ak
import datetime

# 初始化日志配置
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 数据库操作类
class DatabaseHandler:
    def __init__(self, db_config):
        self.db_config = db_config
        self.pool = None

    async def connect(self):
        logging.info("Connecting to the database...")
        self.pool = await aiomysql.create_pool(**self.db_config)
        logging.info("Database connection established.")

    async def insert_signal(self, strategy_id, signal, bar):
        logging.info(f"Inserting signal into database: {signal}")
        async with self.pool.acquire() as conn:
            async with conn.cursor() as cur:
                await cur.execute(
                    "INSERT INTO t_strategy_data (strategy_id, message, open_price, close_price, datetime) VALUES (%s, %s, %s, %s, %s)",
                    (strategy_id, signal, bar['open'], bar['close'], bar['datetime'])
                )
                await conn.commit()
                logging.info("Signal successfully inserted into database.")

    async def close(self):
        logging.info("Closing database connection...")
        self.pool.close()
        await self.pool.wait_closed()
        logging.info("Database connection closed.")

# 数据获取类
class DataFetcher:
    def __init__(self, futures_code):
        self.futures_code = futures_code

    async def get_kline_data(self):
        logging.info("Fetching K line data...")
        await asyncio.sleep(60)  # 模拟异步获取数据
        kline_data = ak.futures_zh_minute_sina(symbol=self.futures_code, period="1")
        logging.info("K line data fetched successfully.")
        return kline_data.tail(10)

# 策略类
class MovingAverageStrategy:
    def __init__(self, data):
        self.data = data

    def calculate_signal(self):
        logging.info("Calculating trading signal...")
        mean_price = self.data['close'].tail(5).mean()
        last_bar = self.data.iloc[-1]
        if last_bar['close'] > mean_price:
            return "买入", last_bar
        elif last_bar['close'] < mean_price:
            return "卖出", last_bar
        else:
            return "持平", last_bar

# 检查是否是交易时间
def is_trading_time():
    now = datetime.datetime.now()
    current_time = now.strftime("%H:%M")
    TRADING_HOURS_DAY = [("09:00", "11:30"), ("13:30", "15:00")]
    TRADING_HOURS_NIGHT = [("21:00", "23:59"), ("00:00", "02:30")]

    for start, end in TRADING_HOURS_DAY:
        if start <= current_time <= end:
            return True
    for start, end in TRADING_HOURS_NIGHT:
        if start <= current_time <= end or (start > end and (current_time >= start or current_time <= end)):
            return True
    return False

# 主程序
async def main():
    # 读取数据库配置
    with open("db_config.json", "r") as file:
        db_config = json.load(file)

    db_handler = DatabaseHandler(db_config)
    await db_handler.connect()

    futures_code = "rb2401"  # 替换为具体的期货代码
    data_fetcher = DataFetcher(futures_code)

    try:
        while True:
            if is_trading_time():
                logging.info("Trading time detected. Running strategy...")
                kline_data = await data_fetcher.get_kline_data()
                strategy = MovingAverageStrategy(kline_data)
                signal, bar = strategy.calculate_signal()
                await db_handler.insert_signal(1, signal, bar)
            else:
                logging.info("Currently outside trading hours. Waiting for next trading period.")
            await asyncio.sleep(60)  # 每分钟检查一次
    finally:
        await db_handler.close()

# 运行主程序
asyncio.run(main())
